import { DgControl, DomService, FormComponentType } from '@farris/designer-services';
import { cloneDeep } from 'lodash-es';

export class TreeNodeMergeRuleService {

    constructor(private domService: DomService) { }

    public getMergeNode(element: any, parentElement: any) {
        const elementType = element.type;
        switch (elementType) {
            case DgControl.ContentContainer.type: {
                return this.checkContentContainerMerge(element, parentElement);
            }
            case DgControl.Component.type: {
                return this.checkComponentMerge(element, parentElement);
            }
            case DgControl.SplitterPane && DgControl.SplitterPane.type: {
                return this.mergeChildContainerNodes(element);
            }
        }
    }
    /**
     * 容器收折规则
     * @param element 容器元素
     * @param parentElement 容器父元素
     */
    private checkContentContainerMerge(element: any, parentElement: any) {

        // 控件本身样式
        const cmpClass = element.appearance && element.appearance.class || '';
        const cmpClassList = cmpClass.split(' ');

        // 页头
        if (cmpClassList.includes('f-page-header')) {
            return this.mergeHeaderNodes(element);
        }
        // 卡片主区域
        if (cmpClassList.includes('f-page-main')) {
            element = this.mergeLikeCardContainerNode(element);

            // 卡片模板的子表区域
            return this.mergeChildContainerNodes(element);
        }

        // 带导航的列表中右侧根容器
        if (cmpClassList.includes('f-page-content-main')) {
            return this.mergeRootLayoutInContainer(element);
        }

        // 滚动监听容器
        if (cmpClassList.includes('f-scrollspy-content')) {
            element = this.mergeLikeCardContainerNode(element);

            // 卡片模板的子表区域
            return this.mergeChildContainerNodes(element);
        }
    }
    /**
     * 隐藏卡片模板中主区域节点（like-card-container层级）
     * f-page-main------f-struct-like-card-----[xxx] 合并为f-page-main-----[xxx] 
     * @param pageMainEle 
     */
    private mergeLikeCardContainerNode(pageMainEle: any) {
        // 若只有一个like-card-container层级，则隐藏掉
        if (!pageMainEle.contents || pageMainEle.contents.length !== 1) {
            return pageMainEle;
        }
        const likeCardEle = pageMainEle.contents[0];
        const likeCardEleCls = likeCardEle && likeCardEle.appearance && likeCardEle.appearance.class || '';
        if (!likeCardEleCls.split(' ').includes('f-struct-like-card')) {
            return pageMainEle;
        }

        // 将like-card-container的子级节点放到like-card-container的父级节点下面
        const clonedpageMainEle = cloneDeep(pageMainEle);
        clonedpageMainEle.contents = likeCardEle.contents || [];

        return clonedpageMainEle;
    }

    /**
     * 带导航的列表中隐藏右侧根容器（f-page的容器节点）
     * @param rootLayoutEle 根容器元素
     * @param parentElement 根容器的父容器
     */
    private mergeRootLayoutInContainer(rootLayoutEleParent: any) {
        if (!rootLayoutEleParent.contents || rootLayoutEleParent.contents.length !== 1) {
            return;
        }
        const rootLayoutEle = rootLayoutEleParent.contents[0];
        const rootLayoutEleCls = rootLayoutEle && rootLayoutEle.appearance && rootLayoutEle.appearance.class || '';
        if (!rootLayoutEleCls.split(' ').includes('f-page')) {
            return rootLayoutEleParent;
        }
        // 将f-page的子级节点放到f-page的父级节点下面
        const clonedrootLayoutEleParentEle = cloneDeep(rootLayoutEleParent);
        clonedrootLayoutEleParentEle.contents = rootLayoutEle.contents || [];

        return clonedrootLayoutEleParentEle;
    }
    /**
     * 页头：
     *  f-page-header：{
     *      f-page-header-base：{
     *          f-title：{
     *              HTMLTemplate
     *          },
     *          ...
     *       },
     *       ...
     *  }
     * 合并为：
     * f-page-header：{
     *      HTMLTemplate,
     *      ...,
     *      ...
     *  }
     * @param pageHeaderEle 页头元素
     */
    private mergeHeaderNodes(pageHeaderEle: any) {
        if (!pageHeaderEle.contents || !pageHeaderEle.contents.length) {
            return;
        }
        const pageHeaderBaseEle = pageHeaderEle.contents[0];
        const pageHeaderBaseCls = pageHeaderEle && pageHeaderBaseEle.appearance && pageHeaderBaseEle.appearance.class || '';
        if (!pageHeaderBaseCls.includes('f-page-header-base')) {
            return;
        }

        if (!pageHeaderBaseEle.contents || !pageHeaderBaseEle.contents.length) {
            return;
        }
        const titleEle = pageHeaderBaseEle.contents[0];
        const titleEleCls = titleEle && titleEle.appearance && titleEle.appearance.class || '';
        if (!titleEleCls.includes('f-title') || !titleEle.contents || !titleEle.contents.length) {
            return;
        }
        // 模板容器
        const htmlTemplateEle = titleEle.contents[0];
        if (htmlTemplateEle.type !== DgControl.HtmlTemplate.type) {
            return;
        }
        const clonedPageHeaderEle = cloneDeep(pageHeaderEle);
        clonedPageHeaderEle.contents = [];

        // 前置任务（筛选条）
        const listFilter = this.domService.selectNode(pageHeaderEle, item => item.type === DgControl.ListFilter.type);

        // 条件全部满足
        clonedPageHeaderEle.contents.push(htmlTemplateEle);
        pageHeaderBaseEle.contents.forEach((c, index) => {
            if (index === 0) {
                return;
            }
            // 提取筛选条容器下的筛选条
            const cls = c && c.appearance && c.appearance.class || '';
            if (listFilter && cls.includes('f-filter-container')) {
                clonedPageHeaderEle.contents.push(listFilter);
            } else {
                clonedPageHeaderEle.contents.push(c);
            }
        });
        pageHeaderEle.contents.forEach((c, index) => {
            if (index === 0) {
                return;
            }
            clonedPageHeaderEle.contents.push(c);
        });
        return clonedPageHeaderEle;

    }


    /**
     * 检查是否满足子表三层结构：Container---Section---Tab
     * @param childContaninerEle 子表区域容器节点
     */
    private checkIsChildContainerNodes(childContaninerEle: any) {
        if (!childContaninerEle.contents || childContaninerEle.contents.length !== 1) {
            return false;
        }
        const sectionEle = childContaninerEle.contents[0];
        const sectionEleCls = sectionEle && sectionEle.appearance && sectionEle.appearance.class || '';
        if (!sectionEleCls.includes('f-section-tabs')) {
            return false;
        }

        if (!sectionEle.contents || sectionEle.contents.length !== 1) {
            return false;
        }
        const tabEle = sectionEle.contents[0];
        const tabEleCls = tabEle && tabEle.appearance && tabEle.appearance.class || '';
        if (!tabEleCls.includes('f-component-tabs')) {
            return false;
        }
        // 条件全部满足
        return true;



    }
    private mergeChildContainerNodes(parentEle: any) {
        if (!parentEle.contents || !parentEle.contents.length) {
            return;
        }

        const clonedParentEle = cloneDeep(parentEle);

        // 查找子表区域节点
        parentEle.contents.forEach((item, index) => {
            if (!item.type === DgControl.ContentContainer.type) {
                return;
            }
            const itemCls = item.appearance && item.appearance.class || '';
            const itemClsList = itemCls.split(' ');
            if (!itemClsList.includes('f-struct-wrapper')) {
                return false;
            }
            const result = this.checkIsChildContainerNodes(item);
            if (result) {
                const tabEle = this.domService.selectNode(item, child => child.type === DgControl.Tab.type);
                clonedParentEle.contents.splice(index, 1, tabEle);
            }
        });


        return clonedParentEle;
    }
    /**
     * 组件Component收折
     * @param cmpEle Component节点
     * @param parentElement 父级元素
     */
    private checkComponentMerge(cmpEle: any, parentElement: any) {
        // 控件本身样式
        const cmpClass = cmpEle.appearance && cmpEle.appearance.class || '';
        const cmpClassList = cmpClass.split(' ');


        switch (cmpEle.componentType) {
            case FormComponentType.dataGrid: case FormComponentType.appointmentCalendar: {
                // 列表DataGrid组件合并层级
                if (cmpClassList.includes('f-struct-is-subgrid')) {
                    return this.mergeChildDataGridComponentNodes(cmpEle);
                }
                // 列表DataGrid组件合并层级
                if (cmpClassList.includes('f-struct-wrapper')) {
                    return this.mergeMainDataGridComponentNodes(cmpEle);
                }
                break;
            }
            case FormComponentType.Frame: {
                return this.mergeRootLayoutInRootComponent(cmpEle);
            }
            case FormComponentType.table: {
                return this.mergeTableComponentNodes(cmpEle);
            }
            default: {
                if (cmpEle.componentType.startsWith('form')) {
                    return this.mergeFormComponentNode(cmpEle);
                }
            }
        }



    }

    /**
     * 收折根组件下的根容器
     * @param cmpEle 根组件Component节点
     */
    private mergeRootLayoutInRootComponent(cmpEle: any) {
        if (!cmpEle.contents || cmpEle.contents.length !== 1) {
            return;
        }
        const rootLayoutEle = cmpEle.contents[0];
        const rootLayoutEleCls = rootLayoutEle && rootLayoutEle.appearance && rootLayoutEle.appearance.class || '';
        if (!rootLayoutEleCls.split(' ').includes('f-page')) {
            return cmpEle;
        }
        // 将f-page的子级节点放到f-page的父级节点下面
        const clonedCmpEle = cloneDeep(cmpEle);
        clonedCmpEle.contents = cloneDeep(rootLayoutEle.contents || []);



        this.mergeQuerySchemeSectionNode(clonedCmpEle);
        return clonedCmpEle;
    }
    /**
     * 列表Component-ContentContainer-DataGrid 三层 合并为Component-DataGrid两层
     * @param cmpEle Component节点
     */
    private mergeChildDataGridComponentNodes(cmpEle: any) {
        // 控件本身样式
        const cmpClass = cmpEle.appearance && cmpEle.appearance.class || '';
        const cmpClassList = cmpClass.split(' ');

        // 子级节点
        const childContents = cmpEle.contents || [];
        const firstChildContent = childContents.length ? childContents[0] : null;
        const firstChildClass = firstChildContent && firstChildContent.appearance ? firstChildContent.appearance.class : '';
        const firstChildClassList = firstChildClass ? firstChildClass.split(' ') : [];

        // 孙子节点
        const grandChildContents = firstChildContent.contents || [];
        const firstGrandChildContent = grandChildContents.length ? grandChildContents[0] : null;
        const firstGrandChildClass = firstGrandChildContent && firstGrandChildContent.appearance ? firstGrandChildContent.appearance.class : '';
        const firstGrandChildClassList = firstGrandChildClass ? firstGrandChildClass.split(' ') : [];


        if (!cmpClassList.includes('f-struct-is-subgrid')) {
            return;
        }

        if (!firstChildContent || firstChildContent.type !== DgControl.ContentContainer.type || !firstChildClassList.includes('f-grid-is-sub')) {
            return;
        }

        if (!firstGrandChildContent || firstGrandChildContent.type !== DgControl.DataGrid.type || !firstGrandChildClassList.includes('f-component-grid')) {
            return;
        }

        //  条件全部满足
        const clonedcmpEle = cloneDeep(cmpEle);
        clonedcmpEle.contents = [];

        clonedcmpEle.contents.push(firstGrandChildContent);

        return clonedcmpEle;
    }

    /**
     * 列表Component-Section-DataGrid 三层 合并为Component-DataGrid两层。
     * 树表Component-Section-TreeGrid 三层，合并为Component-TreeGrid两层。
     * @param cmpEle Component节点
     */
    private mergeMainDataGridComponentNodes(cmpEle: any) {

        // 控件本身样式
        const cmpClass = cmpEle.appearance && cmpEle.appearance.class || '';
        const cmpClassList = cmpClass.split(' ');

        // 子级节点
        const childContents = cmpEle.contents || [];
        const firstChildContent = childContents.length ? childContents[0] : null;
        const firstChildClass = firstChildContent && firstChildContent.appearance ? firstChildContent.appearance.class : '';
        const firstChildClassList = firstChildClass ? firstChildClass.split(' ') : [];

        // 孙子节点
        const grandChildContents = firstChildContent.contents || [];
        const firstGrandChildContent = grandChildContents.length ? grandChildContents[0] : null;
        const firstGrandChildClass = firstGrandChildContent && firstGrandChildContent.appearance ? firstGrandChildContent.appearance.class : '';
        const firstGrandChildClassList = firstGrandChildClass ? firstGrandChildClass.split(' ') : [];


        if (!cmpClassList.includes('f-struct-wrapper')) {
            return;
        }

        if (!firstChildContent || firstChildContent.type !== DgControl.Section.type || !(firstChildClassList.includes('f-section-grid') || firstChildClassList.includes('f-section-treegrid'))) {
            return;
        }
        if (!firstGrandChildContent) {
            return;
        }
        const DataGridEle = this.domService.selectNode(firstChildContent, item => [DgControl.DataGrid.type, DgControl.TreeGrid.type, DgControl.AppointmentCalendar.type].includes(item.type));
        if (!DataGridEle) {
            return;
        }
        const listFilterEle = this.domService.selectNode(firstChildContent, item => item.type === (DgControl.ListFilter && DgControl.ListFilter.type));

        const clonedcmpEle = cloneDeep(cmpEle);
        clonedcmpEle.contents = [];

        // 包含筛选条：将筛选条和DataGrid提取出来
        if (listFilterEle) {
            if (grandChildContents.length === 2 && firstGrandChildClassList.includes('f-filter-container')) {
                clonedcmpEle.contents.push(listFilterEle);
                clonedcmpEle.contents.push(DataGridEle);
                return clonedcmpEle;
            } else {
                return;
            }
        } else {
            // 不包含筛选条：只将DataGrid提取出来
            if (grandChildContents.length === 1 &&
                (firstGrandChildClassList.includes('f-component-grid') || firstGrandChildClassList.includes('f-component-treetable') || firstGrandChildClassList.includes('f-component-appointment-calendar'))) {
                clonedcmpEle.contents.push(DataGridEle);
                return clonedcmpEle;
            }
        }
    }

    /**
     * 卡片Component-Section-Form三层，合并为Component-Form两层
     * @param cmpEle Component节点
     */
    private mergeFormComponentNode(cmpEle: any) {

    }

    /**
     * 隐藏筛选方案容器。Section---QueryScheme
     * @param rootLayoutEle s
     */
    private mergeQuerySchemeSectionNode(parentEle: any) {
        if (!parentEle.contents || !parentEle.contents.length) {
            return parentEle;
        }

        const querySchemeSectionNodeIndex = parentEle.contents.findIndex(item => {
            if (item.type !== DgControl.Section.type) {
                return false;
            }
            const cls = item.appearance && item.appearance.class || '';
            if (cls.split(' ').includes('f-section-scheme') && item.contents && item.contents.length === 1) {
                if (item.contents[0].type === DgControl.QueryScheme.type) {
                    return true;
                }
            }
        });
        if (querySchemeSectionNodeIndex > -1) {
            const querySchemeSectionNode = parentEle.contents[querySchemeSectionNodeIndex];

            parentEle.contents.splice(querySchemeSectionNodeIndex, 1, querySchemeSectionNode.contents[0]);
        }
        return parentEle;

    }

    /**
     * table类型组件收折：Component----Section----Form----Table 收折为Component----Table
     * @param cmpEle 组件节点
     */
    private mergeTableComponentNodes(cmpEle: any) {
        // 控件本身样式
        const cmpClass = cmpEle.appearance && cmpEle.appearance.class || '';
        const cmpClassList = cmpClass.split(' ');

        if (!cmpClassList.includes('f-struct-wrapper')) {
            return;
        }

        const tableEle = this.domService.selectNode(cmpEle, item => item.type === (DgControl.Table && DgControl.Table.type));
        if (!tableEle) {
            return cmpEle;
        }

        const clonedcmpEle = cloneDeep(cmpEle);
        clonedcmpEle.contents = [tableEle];

        return clonedcmpEle;
    }
}
